//
// Created by hjie on 23-6-3.
//

#include "timer_task.h"
#include "loop_event.hpp"
#include <cstdio>

TaskTimer::TaskTimer(LoopEvent *loop_event)
{
    m_loop = loop_event;
    m_task_status.store(false);
}

void TaskTimer::StartTaskTimer()
{
    if (!m_task_status.load())
    {
        m_task_status.store(true);
    }
}

void TaskTimer::StopTaskTimer()
{
    m_task_status.store(false);
}

void TaskTimer::PushTask(int64_t after_time, TaskCallback  && func)
{
    if (m_task_status.load())
    {
        // current time(ms) + after_time
        int64_t current_time = GetCurrentTime() + after_time;
        auto iter = m_task_vec.find(current_time);
        if (iter != m_task_vec.end())
        {
            iter->second.push_back(func);
        }
        else
        {
            m_task_vec[current_time].push_back(func);
        }
    }
}

int64_t TaskTimer::GetCurrentTime()
{
    struct timeval tm = {.tv_sec = 0, .tv_usec = 0};
    gettimeofday(&tm, NULL);
    return (tm.tv_sec * 1000 + tm.tv_usec / 1000);
}

void TaskTimer::DoTimer()
{
    // get current time
    int64_t current_time = GetCurrentTime();
    for (auto iter = m_task_vec.begin(); iter != m_task_vec.end(); )
    {
        if (iter->first < current_time)
        {
            std::vector<std::function<void()>> tasks;
            tasks.swap(iter->second);
            for (auto & func : tasks)
            {
                func();
            }
            iter = m_task_vec.erase(iter);
        }
        else
        {
            iter++;
        }
    }
}

